package controller

import (
	"encoding/json"
	"fmt"
	"go-bluebell/model"
	"go-bluebell/service"
	"go-bluebell/utils"
	"strconv"

	"github.com/gin-gonic/gin"
)

// 以下是社区相关的 controller 逻辑

func CommunityHandler(c *gin.Context) {
	// 查询到所有的社区（community_id, community_name）以列表的形式返回
	data, err := service.GetCommunityList()
	if err != nil {
		code := model.CodeServerBusy
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	model.ResponseSuccess(c, data)
}

// 社区分类详情

func CommunityDetailHandler(c *gin.Context) {
	// 获取社区id
	communityID, err := strconv.ParseInt(c.Param("id"), 10, 64)
	if err != nil {
		code := model.CodeInvalidParam
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	// 根据id获取社区详情
	data, err := service.GetCommunityDetail(communityID)
	if err != nil {
		code := model.CodeServerBusy
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	model.ResponseSuccess(c, data)
}

// 以下是帖子相关的 controller 逻辑

func CreatePostHandler(c *gin.Context) {
	// 获取参数及参数校验（只需要title, content, community_id 这三个参数）
	p := new(model.Post)
	c.ShouldBindJSON(p)

	// 从 context 中获取当前登录的用户 id
	userID, err := utils.GetCurrentUserID(c)
	if err != nil {
		code := model.CodeNeedLogin
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}
	p.AuthorID = userID

	// 创建帖子
	err = service.CreatePost(p)
	if err != nil {
		code := model.CodeServerBusy
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	// 返回响应
	model.ResponseSuccess(c, nil)
}

func GetPostDetailHandler(c *gin.Context) {
	// 获取参数及参数校验
	postID, err := strconv.ParseInt(c.Param("id"), 10, 64)
	if err != nil {
		code := model.CodeInvalidParam
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	// 根据id获取帖子详情
	post, err := service.GetPostByID(postID)
	if err != nil {
		code := model.CodeServerBusy
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	// 返回响应
	model.ResponseSuccess(c, post)
}

func GetPostListHandler(c *gin.Context) {
	// 获取分页参数
	page, err := strconv.Atoi(c.Query("page"))
	if err != nil {
		page = 0
	}
	size, err := strconv.Atoi(c.Query("size"))
	if err != nil {
		size = 10
	}

	// 根据id获取帖子详情
	data, err := service.GetPostList(page, size)
	if err != nil {
		code := model.CodeServerBusy
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	// 返回响应
	model.ResponseSuccess(c, data)
}

// GetPostListHandler2 优化后的获取帖子列表的接口
func GetPostListHandler2(c *gin.Context) {
	// GET请求参数(query string)：/api/v1/posts2?page=1&size=10&order=time
	// 初始化结构体时指定初始参数
	p := &model.PostList{
		Page:  1,
		Size:  10,
		Order: model.OrderTime, // magic string
	}
	//c.ShouldBind()  根据请求的数据类型选择相应的方法去获取数据
	//c.ShouldBindJSON() 如果请求中携带的是json格式的数据，才能用这个方法获取到数据
	if err := c.ShouldBindQuery(p); err != nil {
		code := model.CodeInvalidParam
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}
	data, err := service.GetPostListNew(p) // 更新：合二为一
	// 获取数据
	if err != nil {
		code := model.CodeServerBusy
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}
	model.ResponseSuccess(c, data)
	// 返回响应
}

// 以下是投票相关的 controller 逻辑

func PostVoteController(c *gin.Context) {
	// 参数校验
	// 参数获取 & 参数校验
	var voteTemp model.VoteDataTemp

	// 参数获取 & 参数校验
	data, err := c.GetRawData() // 从c.Request.Body读取请求数据

	fmt.Println("data " + string(data))

	if err != nil {
		code := model.CodeInvalidParam
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	err = json.Unmarshal(data, &voteTemp) // 将json数据解析到结构体中（反序列化）
	if err != nil {
		code := model.CodeInvalidParam
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	vote := model.VoteData{
		PostID:    string(voteTemp.PostID),
		Direction: voteTemp.Direction,
	}

	//vote := new(model.VoteData)
	//if err := c.ShouldBindJSON(vote); err != nil {
	//	fmt.Println(vote.PostID)
	//	fmt.Println(vote.Direction)
	//	_, ok := err.(*validator.ValidationErrors) // 类型断言
	//	if !ok {
	//		code := model.CodeInvalidParam
	//		model.ResponseFailed(c, code, code.Msg(), err)
	//		return
	//	}
	//	return
	//}
	// 获取当前请求的用户的id
	userID, err := utils.GetCurrentUserID(c)
	if err != nil {
		code := model.CodeNeedLogin
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	// 具体投票的业务逻辑
	if err := service.VoteForPost(userID, &vote); err != nil {
		code := model.CodeServerBusy
		model.ResponseFailed(c, code, code.Msg(), err)
		return
	}

	model.ResponseSuccess(c, nil)
}
